package com.vcredit.creditcat.service.product.xrf;

import io.netty.util.internal.StringUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.http.Header;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.vcredit.bird.vo.product.crf.CreditCRFResultDto;
import com.vcredit.creditcat.dto.product.crf.CRFAuthenticationDto;
import com.vcredit.creditcat.dto.product.crf.CRFCallRecordDto;
import com.vcredit.creditcat.dto.product.crf.CRFDeviceInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFGeoDto;
import com.vcredit.creditcat.dto.product.crf.CRFLiveness;
import com.vcredit.creditcat.dto.product.crf.CRFOrderInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFPhoneBookDto;
import com.vcredit.creditcat.dto.product.crf.CRFSocialRelationDto;
import com.vcredit.creditcat.dto.product.crf.CRFUserInfoDto;
import com.vcredit.creditcat.dto.product.crf.CRFVocationDto;
import com.vcredit.creditcat.enumtype.AuthItemEnum;
import com.vcredit.creditcat.enumtype.auth.SupplementItemEnum;
import com.vcredit.creditcat.exception.ResourceException;
import com.vcredit.creditcat.model.AddressList;
import com.vcredit.creditcat.model.AuthPersonalAddress;
import com.vcredit.creditcat.model.CallLog;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.CustSupplementItem;
import com.vcredit.creditcat.model.ProductEnum;
import com.vcredit.creditcat.model.Relative;
import com.vcredit.creditcat.model.base.AbstractItem;
import com.vcredit.creditcat.service.product.IProductApplyNewService;
import com.vcredit.creditcat.service.product.enumtype.ProductEnumType;
import com.vcredit.creditcat.service.product.shared.ProductApplyServiceAdaptor;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.Encrypt;
import com.vcredit.creditcat.util.HttpRequestExt;
import com.vcredit.creditcat.vo.ProductApplyResultVo;
import com.vcredit.creditcat.vo.auth.AuthIdentityExt;
import com.vcredit.creditcat.vo.auth.AuthPersonalInfoExt;
import com.vcredit.creditcat.vo.auth.RelativeListExt;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.util.JacksonUtil;


/**
 * 信而富申请实现类
 * 
 * @author zhaoqi01
 *
 */
@Service(ProductApplyServiceAdaptor.BEANNAME_PREFIX + "25")
public class XRFApplyServiceImpl implements IProductApplyNewService {

	@Value("${crf.return.url}")
	private String returnUrl;

	@Value("${resource.image.url}")
	private String imagUrl;

	@Value("${crf.app.channel}")
	private String appChannel;

	@Value("${crf.salesman.no}")
	private String salesmanNo;

	@Value("${crf.agent.no}")
	private String agentNo;

	/** 对接用的url **/
	@Value("${crf.applay.url}")
	private String creditCrftestUrl;

	@Value("${crf.xinyongmao.dataSource}")
	private String dataSource;

	@Value("${crf.xinyongmao.key}")
	private String key;

	@Value("${crf.promotion.url}")
	private String promotionUrl;

	@Value("${crf.promotion.code}")
	private String promotionCode;

	@Value("${crf.promotion.key}")
	private String promotionKey;

	private static Logger logger = LoggerFactory.getLogger(XRFApplyServiceImpl.class);

	/***
	 * 入口方法
	 */
	@Log
	@Override
	public ProductApplyResultVo apply(Map<Integer, AbstractItem> custAuthInfoMap, Map<Long, CustSupplementItem> custSupplementItemMap, Map<String, Object> otherParams) {
		ProductApplyResultVo productApplyResultVo = new ProductApplyResultVo();
		try {
			Object productCommitParam = this.getProductCommitParam(custAuthInfoMap, custSupplementItemMap,otherParams);
			if(productCommitParam==null){
				productApplyResultVo.setCode(0);
				productApplyResultVo.setMsg("网络开小差, 请重新尝试哦。");
			}
			Map<String, String>  commitOutput = this.commit(productCommitParam);
			if(commitOutput!=null){
				productApplyResultVo.setCode(1);
				productApplyResultVo.setCustProductApply(this.getSaveAuditResultParam(commitOutput));
			}else{
				productApplyResultVo.setCode(0);
				productApplyResultVo.setMsg("网络开小差, 请重新尝试哦。");
			}
		} catch (Exception e) {
			productApplyResultVo.setCode(0);
			productApplyResultVo.setMsg("网络开小差, 请重新尝试哦。");
			logger.error("---------------信而富申请出错!! ", e);
		}
		return productApplyResultVo;
	}

	/**
	 * 提交资料
	 * 
	 * @param submitDto
	 * @return
	 * @throws Exception
	 */
	@Log
	public Map<String, String> commit(Object submitDto) throws Exception {
		Map<String, String> resultMap = new HashMap<>();
		String json = JacksonUtil.Obj2Json(submitDto);
		String signature = Encrypt.base64HmacMD5(key, json);
		signature = signature.replaceAll("\r\n", "");
		logger.info("signature :" + signature);
		try {
			Header[] headers = new Header[3];
			headers[0] = new BasicHeader("X-CrfChina-Signature", signature);
			headers[1] = new BasicHeader("X-Data-Source", dataSource);
			headers[2] = new BasicHeader("Content-Type", "application/json");
			String resultJson = HttpRequestExt.doPut(creditCrftestUrl + "/createOrder", json, "UTF-8", headers);
			if (StringUtil.isNullOrEmpty(resultJson)) {
				resultMap.put("status", "00");
				return resultMap;
			} else {
				String decodeJsonParam = resultJson.replace(":\"\"", ":null");
				CreditCRFResultDto result = JacksonUtil.Json2Obj(decodeJsonParam, new TypeReference<CreditCRFResultDto>() {
				});
				logger.info(result.getMessage());
				resultMap.put("status", "01");
				resultMap.put("message", result.getMessage());
				return resultMap;
			}
		} catch (Exception e) {
			logger.error("------------信而富申请出错!!", e);
			throw e;
		}
	}
	/**
	 * 封装返回实体类
	 * 
	 * @param input
	 * @return
	 * @throws Exception
	 */
	public CustProductApply getSaveAuditResultParam(Map<String, String> input) throws Exception {
		CustProductApply custProductApply = new CustProductApply();
		custProductApply.setAuditTime(ConcurrentDateUtil.formatDateTime(new Date()));
		if ("00".equals(input.get("status"))) {
			custProductApply.setCreditAmt(0);
			custProductApply.setRejectMsg("");
			custProductApply.setSuggestion("");
			custProductApply.setCreditExpiretime("");
			custProductApply.setAuditResult(2);
		} else {
			boolean x=false;
			custProductApply.setRejectMsg(input.get("message"));
			custProductApply.setSuggestion("");
			custProductApply.setCreditAmt(0);
			custProductApply.setCreditExpiretime("");
			custProductApply.setAuditResult(0);
			custProductApply.setIsApply(false);
		}
		return custProductApply;
	}

	/**
	 * 封装提交参数
	 * 
	 * @param itemMap
	 * @param otherParams
	 * @return
	 * @throws ResourceException
	 * @throws Exception
	 */

	@SuppressWarnings("unchecked")
	public Object getProductCommitParam(Map<Integer, AbstractItem> itemMap,Map<Long, CustSupplementItem> custSupplementItemMap, Map<String, Object> otherParams) throws ResourceException, Exception {
		Cust cust = (Cust)otherParams.get("cust");
		CustAccount custAccount = (CustAccount)otherParams.get("custAccount");
		
		RelativeListExt relativeListExt = (RelativeListExt) itemMap.get(AuthItemEnum.CONTACTS.getCode());
		// 紧急联系人
		List<Relative> relativeList = relativeListExt.getRelativeList();
		// 地址
		List<AddressList> addressLists = relativeListExt.getAddressList();
		// 通话记录
		List<CallLog> callLogs = relativeListExt.getCallLogList();
		// 职业信息
		// 人脸识别（基本信息+人脸识别）
		AuthPersonalInfoExt authPersonalInfo = null; // 补充认证项中有就取补充认证项中的基本信息，否则取原始认证项中的基本信息
		if(custSupplementItemMap.get(SupplementItemEnum.XRF_BASE_INFO.getItemId()) == null) {
			authPersonalInfo = (AuthPersonalInfoExt) itemMap.get(AuthItemEnum.BASE_INFO.getCode());
		} else {
			authPersonalInfo = JacksonUtil.Json2Obj(custSupplementItemMap.get(SupplementItemEnum.XRF_BASE_INFO.getItemId()).getDataEntity(), new TypeReference<AuthPersonalInfoExt>(){});
		}
		
		List<AuthPersonalAddress> personalAddrList =authPersonalInfo.getPersonalAddrList();
		// 枚举AuthPersonalInfo id
		List<ProductEnum> findAllList = (List<ProductEnum>) otherParams.get("productEnums");

		// 高级实名
		AuthIdentityExt identity = (AuthIdentityExt) itemMap.get(AuthItemEnum.VERIFY_FACE_PAIR.getCode());

		CRFOrderInfoDto order = new CRFOrderInfoDto();
		order.setOrderId("XYM_" + cust.getCustId());
		// 请求信息
		CRFUserInfoDto userInfo = new CRFUserInfoDto();
		userInfo.setAppChannel(appChannel);
		userInfo.setAgentNo(agentNo);
		userInfo.setSalesmanNo(salesmanNo);
		userInfo.setPhone(custAccount.getUserName());
		order.setUserInfo(userInfo);
		// 身份信息
		CRFAuthenticationDto authenticationDto = new CRFAuthenticationDto();
		authenticationDto.setApplyIdNo(identity.getCitizenId());
		authenticationDto.setApplyName(identity.getName());
		authenticationDto.setIdCardImg(imagUrl + "/" + (identity == null ? identity.getIdFront() : identity.getIdFront()));
		authenticationDto.setIdCardImgBack(imagUrl + "/" + (identity == null ? identity.getIdBack() : identity.getIdBack()));
		order.setAuthentication(authenticationDto);
		// 用户照片信息
		CRFLiveness liveness = new CRFLiveness();
		liveness.setLivenessBlink(imagUrl + "/" + identity.getIdFace());
		order.setLiveness(liveness);
		// 联系人信息
		CRFSocialRelationDto relationDto = new CRFSocialRelationDto();
		for (Relative relative : relativeList) {
			if (relationDto.getFavoriteName() == null && relative.getRelationType().equals(2)) {
				relationDto.setFavoriteName(relative.getRelationName());
				relationDto.setFavoriteTel(relative.getRelationMobile());
				String relationship = this.getProductEnumCode(findAllList, ProductEnumType.relationship.getCode(), relative.getRelation());
				relationDto.setFavoriteRelation(relationship);
				continue;
			}
			if (relationDto.getEmergencyName() == null && relative.getRelationType().equals(1)) {
				relationDto.setEmergencyName(relative.getRelationName());
				relationDto.setEmergencyTel(relative.getRelationMobile());
				String relationship = this.getProductEnumCode(findAllList, ProductEnumType.relationship.getCode(), relative.getRelation());
				relationDto.setEmergencyRelation(relationship);
			}
		}
		order.setSocialRelation(relationDto);

		// 通讯录
		List<CRFPhoneBookDto> crfPhoneBookDtoList = new ArrayList<>();
		Set<String> set = new HashSet<>();
		for (AddressList addressList : addressLists) {
			set.add(addressList.getName());
		}
		for (String name : set) {
			CRFPhoneBookDto crfPhoneBookDto = new CRFPhoneBookDto();
			crfPhoneBookDto.setName(name);
			List<String> phoneList = new ArrayList<>();
			for (AddressList addressList : addressLists) {
				if (addressList.getName().equals(name)) {
					phoneList.add(addressList.getMobile());
				}
			}
			crfPhoneBookDto.setPhone(phoneList);
			crfPhoneBookDtoList.add(crfPhoneBookDto);
		}
		order.setPhoneBook(crfPhoneBookDtoList);
		// 通话记录
		if (callLogs.size() > 0) {
			List<CRFCallRecordDto> list = new ArrayList<>();
			for (CallLog callLog : callLogs) {
				CRFCallRecordDto crfCallRecordDto = new CRFCallRecordDto();
				crfCallRecordDto.setPhone(callLog.getCallerNum());
				crfCallRecordDto.setTime(callLog.getCallTime());
				crfCallRecordDto.setDuration(callLog.getTalkTime());
				crfCallRecordDto.setType(String.valueOf(callLog.getCallType()));
				list.add(crfCallRecordDto);
			}
			order.setCallRecord(list);
		}
		// 职业信息
		CRFVocationDto crfVocationDto = new CRFVocationDto();
		if(personalAddrList == null || personalAddrList.size()<=0){
			return null;
		}
		AuthPersonalAddress address=null;
			for(AuthPersonalAddress authPersonalAddress:personalAddrList){
				if(authPersonalAddress.getAddressType()==0){
					address=authPersonalAddress;
					break;
				}
			}
			if(address==null){
				return null;
			}
			crfVocationDto.setType("2");
			crfVocationDto.setWorkName(address.getAddressName());
			crfVocationDto.setWorkTel(address.getPhone());
			crfVocationDto.setAddress(address.getAddress());
			crfVocationDto.setProvince(address.getProvince());
			crfVocationDto.setCity(address.getCity());
			crfVocationDto.setZone(address.getZone());
			// crfVocationDto.setRoad(address.getRoad());
			crfVocationDto.setProvinceCode(address.getProvinceCode());
			crfVocationDto.setCityCode(address.getCityCode());
			crfVocationDto.setZoneCode(address.getZoneCode());
			crfVocationDto.setIp(address.getIp());
			CRFGeoDto crfGeoDto = new CRFGeoDto();
			crfGeoDto.setAddress(address.getGeoAddress());
			crfGeoDto.setLatitude(address.getGeoLatitude());
			crfGeoDto.setLongitude(address.getGeoLongitude());
			crfGeoDto.setCity(address.getGeoCity());
			crfGeoDto.setDistinct(address.getGeoZone());
			crfGeoDto.setRoad(address.getGeoRoad());
			crfVocationDto.setGeo(crfGeoDto);
		order.setVocation(crfVocationDto);
		// 设备信息
		CRFDeviceInfoDto crfDeviceInfoDto = new CRFDeviceInfoDto();
		crfDeviceInfoDto.setPhone(custAccount.getUserName());
		crfDeviceInfoDto.setImei(otherParams.get("deviceNo").toString());
		crfDeviceInfoDto.setMobileDevice(otherParams.get("phoneModel").toString());
		crfDeviceInfoDto.setOsType(otherParams.get("operatingSys").toString().toLowerCase().matches("android.*") ? "android" : "ios");
		order.setDeviceInfo(crfDeviceInfoDto);
		// 回调 url
		order.setReturnUrl(returnUrl);
		
		logger.info("------------信而富申请提交参数  CRFOrderInfoDto：" + JacksonUtil.Obj2Json(order));
		return order;
	}

	public String getProductEnumCode(List<ProductEnum> findAllList, Integer enumType, Integer catCode) {
		String productCode = "";
		for (ProductEnum productEnum : findAllList) {
			Integer enumTypeLocal = productEnum.getEnumType();
			Integer catCodeLoal = productEnum.getCatCode();
			if (enumTypeLocal == enumType && catCodeLoal == catCode) {
				productCode = productEnum.getProductCode();
			}
		}
		return productCode;
	}
}
